package pearson.automation.forms.courseDetails.module;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.testng.Assert;

import pearson.automation.assets.AssetWithOutRollOver;
import pearson.automation.assets.BaseAsset;
import pearson.automation.forms.PreparedWikiPage;
import pearson.automation.forms.RightHandPanel;
import pearson.automation.forms.SearchResultsForm.AssetCategory;
import pearson.automation.forms.SectionContents;
import pearson.automation.forms.RightHandPanel.RightHandPanelTab;

import framework.BaseForm;
import framework.elements.Button;
import framework.elements.ElementList;
import framework.elements.Label;
import framework.elements.TextBox;

public class SectionForm extends BaseForm {

    private static final Label identifyer =
        new Label(By.className("section_area"), "Section area");
    protected Label title = new Label(By.cssSelector(
            "div[data-type='title'] h1[class*='section_title']"),
                "Title");
    private final TextBox titleEditor = new TextBox(By.cssSelector(
            "div[data-type='title'] textarea[class*='section_title']"),
                "Title");
    protected Label subtitle = new Label(By.cssSelector(
            "div[data-type='subtitle'] *[class*='section_subtitle']"),
                "Subtitle");
    protected TextBox subtitleEditor = new TextBox(By.cssSelector(
            "div[data-type='subtitle'] textarea[class*='section_title']"),
                "Subtitle");
    protected Label chapter = new Label(By.cssSelector(
            "div[class*='section_content'] > p"), "Chapter");
    private final Label nonEditableError = new Label(By.xpath(
            "//div[text()=\"Sorry, you don't have the permission to edit the content.\"]"),
                "Non-editable section context");
    private final Label noAssetsError = new Label(By.xpath(
            "//div[text()=\"Sorry, you don't have the permission to add assets.\"]"),
                "Non-editable section context");
    private final Button close = new Button(
            By.className("js-popup-close"), "Close");

    protected String chapterXpath =
        "//p[@data-content-ref][contains(.,'%1$s')]";
    protected String chapterLinkXPath =
        "//p[@data-content-ref]/a[@href='%1$s'][text()='%1$s']";
    protected final String assetXpathTemplate =
        "//div[contains(@class,'section_content')]//p[text()='%1$s']";
    protected final String assetDeleteXpathTemplate =
        "//div[@data-content-ref='%1$s']//div[@class='delete']";

    public SectionForm() {
        super(identifyer.getLocator(), identifyer.getName());
    }

    protected SectionForm(final By locator, final String name) {
        super(locator, name);
    }

    public final String getTitle() {
        return title.getText();
    }

    public final void setTitle(String titleVal) {
        title.click();
        titleEditor.setText(titleVal);
        chapter.clickAndWait();
    }

    public final String getSubtitle() {
        return subtitle.getText();
    }

    public final void setSubtitle(final String subtitleVal) {
        subtitle.click();
        subtitleEditor.setText(subtitleVal);
        title.click();
    }

    public void setChapter(String value) {
        chapter.clickAndWait();
        WebElement activeElement = browser.getDriver().switchTo().activeElement();
        activeElement.sendKeys(value, Keys.ENTER);
        title.click();
    }

    public String getChapter() {
        return chapter.getText();
    }

    public void assertNotEditable() {
        chapter.click();
        nonEditableError.assertIsPresent();
        close.clickAndWait();
    }

    public void closeNoPermission() {
        noAssetsError.assertIsPresent();
        close.clickAndWait();
    }

    public void assertChapterPresent(String chapterValue) {
        if (chapterValue.contains("'")) {
            Assert.assertTrue(
                    Arrays.asList(getChapters()).contains(chapterValue),
                String.format("Asset %1$s has not been found", chapterValue));
        } else {
            new Label(By.xpath(String.format(
                    chapterXpath, chapterValue)), chapterValue)
                .assertIsPresent();
        }
    }

    public void assertChapterAbsent(String chapterValue) {
        new Label(By.xpath(
            String.format(chapterXpath, chapterValue)), chapterValue)
        .assertIsAbsent();
    }

    public String dragAssetFromRHPanelToChapter(
            String chapterValue,
            RightHandPanelTab tab) {
        RightHandPanel rightHand = new SectionContents().openRightHandPanel();
        rightHand.openTab(tab);
        
        if (tab == RightHandPanelTab.LIBRARY) {
            //Switch to Images tab, as first asset might not be draggable to contents
            rightHand.openCategoriesSelectorInSearchBox();
            rightHand.selectSearchCategory(AssetCategory.IMAGES);
        }
    
        String[] assetName;
        BaseAsset asset;
        try {
            assetName = rightHand.getAssets().get(0);
            asset = new AssetWithOutRollOver(assetName[0]);
        } catch (IndexOutOfBoundsException e) {
            fatal("No asset in the Right Hand Panel");
            return null;
        }
        asset.dragToElement(new Label(By.xpath(String.format(
                chapterXpath, chapterValue)), chapterValue).getElement());
        return assetName[0];
    }

    public void assertAssetPresent(String assetName) {
        new AssetWithOutRollOver(String.format(
                assetXpathTemplate, assetName), true).assertIsPresent();
    }

    public void assertAssetAbsent(String assetName) {
        Assert.assertFalse(new AssetWithOutRollOver(
            String.format(assetXpathTemplate, assetName), true).isPresent(),
            "Asset is present");
    }

    public void deleteChapter(String chapterValue) {
        Label chapter = new Label(By.xpath(
                String.format(chapterXpath, chapterValue)), chapterValue);
        chapter.clickAndWait();
        WebElement activeElement =
            browser.getDriver().switchTo().activeElement();
        int size = chapterValue.length();
        for (int i = 0; i < size; i++) {
            activeElement.sendKeys(Keys.DELETE);
        }
        title.click();
    }

    public void modifyChapter(
            String oldChapter,
            String suffixChapter,
            int insertIndex) {
        Label chapter = new Label(By.xpath(
                String.format(chapterXpath, oldChapter)), oldChapter);
        chapter.clickAndWait();
        WebElement activeElement =
            browser.getDriver().switchTo().activeElement();
        String arrows = "";
    
        for (int i = 0; i < insertIndex; i++) {
            arrows += Keys.ARROW_RIGHT;
        }
    
        activeElement.sendKeys(arrows);
        activeElement.sendKeys(suffixChapter);
        title.click();
    }

    public void modifyChapter(
            String oldChapter,
            String replaceString,
            String suffixChapter) {
        Label chapter = new Label(By.xpath(
                String.format(chapterXpath, oldChapter)), oldChapter);
        chapter.clickAndWait();
        WebElement activeElement =
            browser.getDriver().switchTo().activeElement();
        String arrows = "";
    
        for (int i = 0; i < oldChapter.indexOf(replaceString); i++) {
            arrows += Keys.ARROW_RIGHT;
        }
    
        activeElement.sendKeys(arrows);
        arrows = "";
        for (int i = 0; i < replaceString.length(); i++) {
            arrows += Keys.DELETE;
        }
        activeElement.sendKeys(arrows);
        activeElement.sendKeys(suffixChapter);
        title.clickAndWait();
    }

    public void deleteChapterSubstring(
            String oldChapter,
            String suffixChapter) {
        Label chapter = new Label(By.xpath(
                String.format(chapterXpath, oldChapter)), oldChapter);
        chapter.clickAndWait();
        WebElement activeElement =
            browser.getDriver().switchTo().activeElement();
        int size = oldChapter.indexOf(suffixChapter);
        String arrows = "";
    
        for (int i = 0; i < size; i++) {
            arrows += Keys.ARROW_RIGHT;
        }
    
        activeElement.sendKeys(arrows);
        arrows = "";
        size = suffixChapter.length();
        for (int i = 0; i < size; i++) {
            arrows += Keys.DELETE;
        }
        activeElement.sendKeys(arrows);
        title.clickAndWait();
    }

    public String[] getChapters() {
        ElementList chapters = new ElementList(
                By.xpath(String.format(chapterXpath, "")), "Chapters");
        List<WebElement> chapterList = chapters.getListElements();
        String[] res = new String[chapterList.size()];
        for (int i = 0; i < res.length; i++) {
            res[i] = chapterList.get(i).getText();
        }
        return res;
    }

    public void cleanupChapter(int sumLength) {
        Label chapter = new Label(By.xpath(
                String.format(chapterXpath, "")), "Chapter");
        chapter.clickAndWait();
        WebElement activeElement = browser.getDriver().switchTo().activeElement();
        String arrows = "";
        for (int i = 0; i < sumLength * 2; i++) {
            arrows += Keys.DELETE;
        }
        activeElement.sendKeys(arrows);
        title.clickAndWait();
    }

    public void copyToChapter(String preparedPage) {
        browser.openNewPage(preparedPage);
        PreparedWikiPage page = new PreparedWikiPage();
        page.copyPreparedText();
        browser.selectPreviousWindow();
        Label chapter = new Label(By.xpath(
                String.format(chapterXpath, "")), "Chapter");
        chapter.clickAndWait();
        WebElement activeElement =
            browser.getDriver().switchTo().activeElement();
        activeElement.sendKeys(Keys.chord(Keys.SHIFT, Keys.INSERT));
        try {
            Thread.sleep(3000);
            activeElement.click();
            title.click();
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void checkChapterPaste() {
        ArrayList<String> chapterContentArr =
            PreparedWikiPage.getPreparedChapterInnerHtml();
        try {
            Thread.sleep(5000);
            
            List<WebElement> chapters = new ElementList(By.xpath(
                    String.format(chapterXpath, "")), "Chapter")
                    .getListElements();
            ArrayList<String> actual_chapters = new ArrayList<String>();
            for (WebElement chapter: chapters){
                actual_chapters.add(chapter.getAttribute("innerHTML"));
            }
            info("Actual:" + actual_chapters.toString());
            info("Expected:" + chapterContentArr.toString());
            
            Assert.assertEquals(
                    actual_chapters.toArray(), chapterContentArr.toArray(),
                    "Chapters are copied incorrectly");
        } catch (IndexOutOfBoundsException e) {
            e.printStackTrace();
            fatal("Chapters are copied incorrectly");
    
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void assertLinkChapterPresent(String chapterValue) {
        new Label(By.xpath(String.format(
                chapterLinkXPath, chapterValue)), chapterValue)
        .assertIsPresent();
    }

    public void addChapterAtEnd(String chapterValue) {
        setChapter(Keys.chord(Keys.CONTROL, Keys.END)
                 + Keys.ENTER + chapterValue);
    }
}
